package web;

import java.io.IOException;
import java.net.SocketTimeoutException;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import repository.implementation.DataBaseWorker;
import repository.implementation.RecipeModel;
import repository.implementation.RegistrationRepository;

public class CrawlerWorker implements Runnable
{
	private CrawlerRegistration registration;
	private RegistrationRepository modelRepository;
	private boolean stopWorking;
	private DataBaseWorker dbWorkers[];
	private static int workerID = 0;
	private int localId;

	public CrawlerWorker(CrawlerRegistration registration,
			RegistrationRepository modelRepository, DataBaseWorker dbWorkers[])
	{
		workerID++;
		localId = workerID;
		this.registration = registration;
		this.modelRepository = modelRepository;
		stopWorking = false;
		this.dbWorkers = dbWorkers;
	}

	// public void stopWorker()
	// {
	// stopWorking = true;
	// }

	private void notifyForLeavingWork()
	{
		for (int i = 0; i < dbWorkers.length; i++)
			dbWorkers[i].StopWorker(localId);
	}

	@Override
	public void run()
	{
		try
		{
			String currentUrl = "";
			Document doc = null;
			Elements divs = null;
			RecipeModel model = null;
			System.out.println("CrawlerWorker #" + localId + " started working...");
			while (true && !stopWorking)
			{
				currentUrl = registration.UnregisterUrl();

				if (currentUrl.equalsIgnoreCase("EXIT"))
					break;
				
				doc = Jsoup.connect(currentUrl).timeout(60 * 1000).get();
				divs = doc.select(".ingredient-wrap");
				model = new RecipeModel();
				for (Element div : divs)
				{
					Elements unsortedLists = div.select("#liIngredient");
					for (Element listItem : unsortedLists)
					{
						// System.out.println("information: data-grams = " +
						// listItem.attr("data-grams")
						// +"  url = " + currentUrl);
						model.ingredientMetric.add("gram");
						model.ingredientName.add(listItem
								.select("span#lblIngName").first().text());
						model.ingredientQuantity.add(new Double(listItem
								.attr("data-grams")));
						model.recipeContent += listItem.text() + "\n";
					}
				}

				model.recipeName = doc.select("#itemTitle").first().text();
				model.recipePicUrl = doc.select("#imgPhoto").first()
						.absUrl("src");
				// model.recipeTime =
				// Integer.parseInt(doc.select("span.time em")
				Elements anyHour = doc.select("span#totalHoursSpan em");
				int hour = anyHour.isEmpty() ? 0 : Integer.parseInt(anyHour
						.first().text());
				Elements anyMin = doc.select("span#totalMinsSpan em");
				int min = anyMin.isEmpty() ? 0 : Integer.parseInt(anyMin
						.first().text());

				model.recipeTime = hour * 60 + min;
				model.recipeContent += doc.select(".directLeft").first().text();
				model.recipeUrl = currentUrl;

				modelRepository.RegisterNewRecipe(model);
			}
			
			System.out.println("CrawlerWorker #" + localId + " leaving work...");
			notifyForLeavingWork();
			model.recipeName = "EXIT";
			Thread.sleep(500);
			modelRepository.RegisterNewRecipe(model);

		} catch (SocketTimeoutException e)
		{
			System.out.println(e.getMessage());
			System.out.println("CrawlerWorker #" + localId + " leaving work unexpectedly...");
			notifyForLeavingWork();

		} catch (NumberFormatException n)
		{
			// System.out.println(n.getMessage());
			System.out.println("CrawlerWorker #" + localId + " leaving work unexpectedly...");
			notifyForLeavingWork();
			n.printStackTrace();
			

		} catch (InterruptedException e)
		{
			System.out.println("CrawlerWorker #" + localId + " leaving work unexpectedly...");
			notifyForLeavingWork();
			e.printStackTrace();

		} catch (IOException e)
		{
			System.out.println("CrawlerWorker #" + localId + " leaving work unexpectedly...");
			notifyForLeavingWork();
			e.printStackTrace();
		}
	}
}
